package com.songlanyun.modules.marketing.groupbuy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.enums.LockPrefixConstant;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.utils.custom.ClassConvertUtils;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.modules.marketing.groupbuy.entity.GroupBuyActivityGoods;
import com.songlanyun.modules.marketing.groupbuy.entity.GroupBuyTeam;
import com.songlanyun.modules.marketing.groupbuy.model.vo.*;
import com.songlanyun.modules.marketing.groupbuy.service.GroupBuyActivityGoodsService;
import com.songlanyun.modules.marketing.groupbuy.service.GroupBuyActivityService;
import com.songlanyun.modules.marketing.groupbuy.service.GroupBuyTeamService;
import com.songlanyun.modules.order.entity.ChildOrder;
import com.songlanyun.modules.order.entity.Order;
import com.songlanyun.modules.order.service.OrderService;
import org.apache.commons.lang.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.marketing.groupbuy.dao.GroupBuyTeamMemberDao;
import com.songlanyun.modules.marketing.groupbuy.entity.GroupBuyTeamMember;
import com.songlanyun.modules.marketing.groupbuy.service.GroupBuyTeamMemberService;


@Service("groupBuyTeamMemberService")
public class GroupBuyTeamMemberServiceImpl extends ServiceImpl<GroupBuyTeamMemberDao, GroupBuyTeamMember> implements GroupBuyTeamMemberService {


    @Autowired
    private GroupBuyActivityService groupBuyActivityService;

    @Autowired
    private GroupBuyActivityGoodsService groupBuyActivityGoodsService;


    @Autowired
    private GroupBuyTeamService groupBuyTeamService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public GroupBuyTeamMember create(GroupBuyTeamMember entity) {
        ValidatorUtils.validateEntity(entity);
        this.baseMapper.insert(entity);
        return entity;
    }

    @Override
    public GroupBuyTeamMember modify(GroupBuyTeamMember entity) {
        ValidatorUtils.validateEntity(entity);
        this.baseMapper.updateById(entity);
        return entity;
    }

    @Override
    public void remove(Long id) {

    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<GroupBuyTeamMember> page = this.page(
                new Query<GroupBuyTeamMember>().getPage(params),
                new QueryWrapper<GroupBuyTeamMember>()
        );

        return new PageUtils(page);
    }

    /**
     * 获取所有团长支付过期的成员()
     * @return
     */
    @Override
    public List<GroupBuyTeamMember> loadLeaderPayExpire() {
        return this.list(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getLeader,true)
                .eq(GroupBuyTeamMember::getPayStatus,OrderConstant.PaymentStatus.NO_PAY)
                .ge(GroupBuyTeamMember::getPayExpireTime,0)
                .le(GroupBuyTeamMember::getPayExpireTime,System.currentTimeMillis()-2*60*1000)
        );
    }

    /**
     * 获取所有支付过期的成员
     * @return
     */
    @Override
    public List<GroupBuyTeamMember> loadMemberPayExpire() {
        return this.list(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getLeader,false)
                .eq(GroupBuyTeamMember::getPayStatus,OrderConstant.PaymentStatus.NO_PAY)
                .ge(GroupBuyTeamMember::getPayExpireTime,0)
                .le(GroupBuyTeamMember::getPayExpireTime,System.currentTimeMillis()-2*60*1000)
        );
    }

    /**
     * 获取团下面的所有成员
     * @param teamId
     * @return
     */
    @Override
    public List<GroupBuyTeamMember> loadAllMember(Long teamId) {
        return this.list(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getBuyTeamId,teamId)
        );
    }

    /**
     * 获取团下面所有参与成功的成员
     * @param teamId
     * @return
     */
    @Override
    public List<GroupBuyTeamMember> loadJoinSuccessMember(Long teamId) {
        return this.list(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getBuyTeamId,teamId)
                .eq(GroupBuyTeamMember::getJoinStatus,true)
        );
    }

    /**
     * 获取团下面所有支付成功的成员
     * @param teamId
     * @return
     */
    @Override
    public List<GroupBuyTeamMember> loadValidMember(Long teamId) {
        return this.list(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getBuyTeamId,teamId)
                .eq(GroupBuyTeamMember::getJoinStatus,true)
                .eq(GroupBuyTeamMember::getPayStatus, OrderConstant.PaymentStatus.SUCCESS)
        );
    }


    /**
     * 获取团下面所有支付成功的成员人数
     * @param teamId
     * @return
     */
    @Override
    public Integer loadValidMemberCount(Long teamId) {
        return this.count(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getBuyTeamId,teamId)
                .eq(GroupBuyTeamMember::getJoinStatus,true)
                .eq(GroupBuyTeamMember::getPayStatus, OrderConstant.PaymentStatus.SUCCESS)
        );
    }

    /**
     * 获取团下面所有参与成功的成员人数
     * @param teamId
     * @return
     */
    @Override
    public Integer loadJoinSuccessCount(Long teamId) {
        return this.count(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getBuyTeamId,teamId)
                .eq(GroupBuyTeamMember::getJoinStatus,true)
        );
    }

    @Override
    public GroupBuyTeamMember getMemberBy(Long teamId, Long userId) {
        return this.getOne(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getBuyTeamId,teamId)
                .eq(GroupBuyTeamMember::getUserId,userId)
                .last("limit 1")
        );
    }

    /**
     * 团成员支付过期
     * @param order
     */
    @Override
    public void memberPayExpireHandler(Order order) {
        GroupBuyTeam groupBuyTeam = groupBuyTeamService.loadById(order.getSponsorActivityId(), false);
        if(groupBuyTeam!=null)
        {
            GroupBuyTeamMember member = this.getMemberBy(groupBuyTeam.getId(), order.getUserId());
            if(member.getLeader())
            {
                leaderPayExpireHandler(member);
            }
            else
            {
                memberPayExpireHandler(member);
            }

            //回退拼团库存=========================================================
            ChildOrder childOrder = order.getChildOrderList(true).get(0);
            RLock lock = redissonClient.getLock(LockPrefixConstant.GROUP_BUY_GOODS + groupBuyTeam.getGroupBuyGoodsId());
            lock.lock(2, TimeUnit.SECONDS);
            try  {
                GroupBuyActivityGoods groupBuyActivityGoods = groupBuyTeam.getGroupBuyActivityGoods();
                groupBuyActivityGoodsService.release(groupBuyActivityGoods,childOrder.getNumber());
                groupBuyActivityGoods.decSaleNum(childOrder.getNumber());
                groupBuyActivityGoodsService.updateById(groupBuyActivityGoods);
            }
            finally {
                lock.unlock();
            }
        }

    }

    @Override
    public PageUtils queryMyJoinTeamOrderPage(Map<String, Object> params) {

        IPage<GroupBuyOrderSlimVO> page = this.baseMapper.queryMyJoinTeamOrderPage(new Query<GroupBuyOrderSlimVO>().getPage(params),paramsMapToReq(params));
        page.getRecords().forEach(o->{
            List<TeamMemberUserInfoVO> teamMembers = this.baseMapper.getTeamMembers(o.getBuyTeamId());
            o.setMemberInfos(teamMembers);
        });
        return new PageUtils(page);
    }

    @Override
    public List<GroupBuyTeamMemberSlimVO> queryMembers(Map<String, Object> params) {
        List<GroupBuyTeamMemberSlimVO> list = this.baseMapper.queryMembers(paramsMapToReq(params));
        return list;
    }

    @Override
    public GroupBuyOrderVO getByMemberOrder(Long userId, Long memberId) {
        GroupBuyOrderVO groupBuyOrderVO = new GroupBuyOrderVO();
        GroupBuyTeamMember member = this.getOne(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getUserId, userId)
                .eq(GroupBuyTeamMember::getId, memberId)
                .last("limit 1"));

        if(member==null){
            return null;
        }
        groupBuyOrderVO.setMember(member);

        GroupBuyTeam team = groupBuyTeamService.getById(member.getBuyTeamId());
        groupBuyOrderVO.setTeam(team);

        Order order = orderService.loadByUserIdAndId(userId, member.getOrderId(), false);
        order.loadOrderReceipt();
        order.loadOrderSelfTake();
        order.getChildOrderList(true);
        groupBuyOrderVO.setOrder(order);

        List<TeamMemberUserInfoVO> teamMembers = this.baseMapper.getTeamMembers(member.getBuyTeamId());
        groupBuyOrderVO.setMemberInfos(teamMembers);

        return groupBuyOrderVO;
    }

    /**
     * 拼团成员的订单
     * @param orderId
     * @return
     */
    @Override
    public GroupBuyOrderVO getByMemberOrder(Long orderId) {
        Order order = orderService.getById(orderId);
        Long userId = order.getUserId();

        GroupBuyOrderVO groupBuyOrderVO = new GroupBuyOrderVO();
        GroupBuyTeamMember member = this.getOne(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getUserId, userId)
                .eq(GroupBuyTeamMember::getOrderId, orderId)
                .last("limit 1"));


        order.loadOrderReceipt();
        order.loadOrderSelfTake();
        order.getChildOrderList(true);
        groupBuyOrderVO.setOrder(order);

        List<TeamMemberUserInfoVO> teamMembers = this.baseMapper.getTeamMembers(member.getBuyTeamId());
        groupBuyOrderVO.setMemberInfos(teamMembers);
        return groupBuyOrderVO;
    }

    @Override
    public List<TeamMemberUserInfoVO> getTeamMembers(Long teamId) {
        return this.baseMapper.getTeamMembers(teamId);
    }

    @Override
    public GroupBuyTeamMember getByOrderIdAndUserId(Long orderId, Long userId) {
        GroupBuyTeamMember member = this.getOne(new LambdaQueryWrapper<GroupBuyTeamMember>()
                .eq(GroupBuyTeamMember::getUserId, userId)
                .eq(GroupBuyTeamMember::getOrderId, orderId)
                .last("limit 1"));
        return member;
    }


    private TeamOrderPageReq paramsMapToReq(Map<String, Object> params) {
        TeamOrderPageReq pageReq = new TeamOrderPageReq();
        if (params.get("shop_id") != null) {
            pageReq.setShopId(ClassConvertUtils.objToLong(params.get("shop_id").toString()));
        }
        if (params.get("user_id") != null) {
            pageReq.setUserId(ClassConvertUtils.objToLong(params.get("user_id").toString()));
        }
        if (params.get("status") != null) {
            pageReq.setStatus(ClassConvertUtils.objToInteger(params.get("status")));
        }

        if (params.get("team_id") != null) {
            pageReq.setTeamId(ClassConvertUtils.objToLong(params.get("team_id")));
        }

        if (params.containsKey("mobile") && StringUtils.isNotBlank(params.get("mobile").toString())) {
            pageReq.setMobile(params.get("mobile").toString());
        }

        if (params.containsKey("nickname") && StringUtils.isNotBlank(params.get("nickname").toString())) {
            pageReq.setMobile(params.get("nickname").toString());
        }

        return pageReq;

    }

    /**
     * 团长支付过期处理
     * @param member
     * @return
     */
    private GroupBuyTeamMember leaderPayExpireHandler(GroupBuyTeamMember member) {
       if(OrderConstant.PaymentStatus.NO_PAY.equals(member.getPayStatus()))
       {
           //修改成员状态
           member.setJoinStatus(false);
           member.setPayStatus(OrderConstant.PaymentStatus.EXPIRE);
           this.modify(member);

           //修改团状态
           GroupBuyTeam groupBuyTeam = member.loadGroupBuyTeam();
           groupBuyTeam.setStatus(OrderConstant.TeamStatus.CREAT_FAIL);
           groupBuyTeamService.modify(groupBuyTeam);

       }
       return member;
    }


    /**
     * 普通成员过欺处理
     * @param member
     * @return
     */
    private GroupBuyTeamMember memberPayExpireHandler(GroupBuyTeamMember member) {
        if(OrderConstant.PaymentStatus.NO_PAY.equals(member.getPayStatus()))
        {
            //修改成员状态
            member.setJoinStatus(false);
            member.setPayStatus(OrderConstant.PaymentStatus.EXPIRE);
            this.modify(member);
        }
        return member;
    }


    @Override
    public GroupBuyTeamMember createMember(GroupBuyTeam team, Order order, Boolean isLeader) {
        ChildOrder childOrder = order.getChildOrderList(true).get(0);
        GroupBuyTeamMember groupBuyTeamMember = new GroupBuyTeamMember();
        groupBuyTeamMember.setBuyTeamId(team.getId());
        groupBuyTeamMember.setShopId(team.getShopId());
        groupBuyTeamMember.setGroupBuyId(team.getGroupBuyId());
        groupBuyTeamMember.setGroupBuyGoodsId(team.getGroupBuyGoodsId());
        groupBuyTeamMember.setBuyTeamId(team.getId());
        groupBuyTeamMember.setUserId(order.getUserId());
        groupBuyTeamMember.setUserMobile(childOrder.getMobile());
        groupBuyTeamMember.setLeader(isLeader);
        groupBuyTeamMember.setOrderId(order.getId());
        groupBuyTeamMember.setOrderCode(order.getOrderCode());
        groupBuyTeamMember.setJoinTime(new Date());
        groupBuyTeamMember.setPayTime(null);
        groupBuyTeamMember.setPayExpireTime(team.getGroupBuyActivity().getPayExpireTime(System.currentTimeMillis()));
        groupBuyTeamMember.setPayStatus(OrderConstant.PaymentStatus.NO_PAY);
        groupBuyTeamMember.setJoinStatus(true);
        groupBuyTeamMember.setRightsStatus(OrderConstant.RightsStatus.NO);
        groupBuyTeamMember.setMemberRightsType(OrderConstant.MemberRightsType.NO);
        groupBuyTeamMember.setPayOrderId(order.getPayOrderId());

        groupBuyTeamMember.setShopName(order.getShopName());
        groupBuyTeamMember.setGoodsId(childOrder.getGoodsId());
        groupBuyTeamMember.setGoodsTitle(childOrder.getGoodsTitle());
        groupBuyTeamMember.setShortGoodsTitle(childOrder.getShortGoodsTitle());
        groupBuyTeamMember.setGoodsImg(childOrder.getGoodsImg());
        groupBuyTeamMember.setSingleGoodsId(childOrder.getSingleGoodsId());
        groupBuyTeamMember.setSkuSetName(childOrder.getSkuSetName());
        groupBuyTeamMember.setSkuHashCode(childOrder.getSkuHashCode());
        groupBuyTeamMember.setRealFreight(order.getRealFreight());
        groupBuyTeamMember.setRealPrice(childOrder.getRealPrice());
        groupBuyTeamMember.setTotalRealPrice(childOrder.getTotalRealPrice());
        groupBuyTeamMember.setTotalAmount(order.getTotalAmount());
        groupBuyTeamMember.setTotalReduced(order.getTotalReduced());
        groupBuyTeamMember.setChildOrderId(childOrder.getId());
        groupBuyTeamMember.setNumber(childOrder.getNumber());


        this.create(groupBuyTeamMember);
        return groupBuyTeamMember;
    }







}
